<template>
  <article class="page page-wyuc-decrypt">
    <h4 class="text-center">云音乐缓存文件解码</h4>
    <form class="form">
      <div class="form-group">
        <div class="alert alert-info" role="alert">
          <div>注：解码后的文件会直接存放在原文件所在目录。</div>
        </div>
      </div>
      <div class="form-group form-main">
        <fieldset>
          <legend>文件列表</legend>
          <div class="fieldset-content">
            <div class="table-header" :style="thStyles">
              <table>
                <tbody>
                  <tr>
                    <th v-for="(v,i) in tableHeaders" :key="`th_${i}`" :style="{width: v.width}">{{v.label}}</th>
                  </tr>
                </tbody>
              </table>
            </div>
            <div class="table-body" @drop.prevent="filesDrop" @dragover.prevent>
              <table ref="table">
                <tbody>
                  <tr v-for="(v,i) in filesList" :key="`file_${i}`">
                    <td v-for="(item,index) in tableHeaders" :key="`td_${i}_${index}`" :style="{width: item.width}">
                      <div v-if="item.value==='status'">{{fileStatusList[v.status]}}</div>
                      <div v-else-if="item.value==='action'">
                        <button type="button" class="btn btn-link btn-sm" @click.stop="fileItemDelete(i)">删除</button>
                      </div>
                      <span v-else>{{v[item.value] || ''}}</span>
                    </td>
                  </tr>
                  <tr v-if="filesList.length===0" class="nodata-tr"><td>将待处理的UC文件拖动到此处</td></tr>
                </tbody>
              </table>
            </div>
          </div>
        </fieldset>
      </div>
      <div class="form-group text-center">
        <x-button type="default" @click="clearAll" :loading="loadingCount > 0">清空</x-button>
        <x-button type="primary" @click="submitForm" :loading="loadingCount > 0">开始解码</x-button>
      </div>
      <div v-if="loadingCount > 0" class="mask">
        <x-loading></x-loading>
      </div>
    </form>
  </article>
</template>

<script>
const fs = global.require('fs')
const path = global.require('path')
let {formatFileSize}  = global.$jstools || {}

export default {
  name: 'wyuc-decrypt',
  data () {
    return {
      filesList: [],
      fileHeaderMarks: {
        MP3: [0x49, 0x44, 0x33],
        WAV: [0x52, 0x49, 0x46],
        wav: [0x57, 0x41, 0x56, 0x45],
        WMA: [0x30, 0x26, 0xB2],
      },
      fileMimeType: {
        'mp3': 'audio/mpeg',
        'wav': 'audio/x-wav',
        'mid': 'audio/midi',
        'midi': 'audio/midi',
        'm3u': 'audio/x-mpegurl',
        'm4a': 'audio/x-m4a',
        'ogg': 'audio/ogg',
        'ra': 'audio/x-realaudio',
      },
      fileStatusList: ['未处理', '正在处理', '已处理', '处理失败'],
      tableHeaders: [
        {label: '文件名', value: 'name', width: '70%'},
        // {label: '大小', value: 'size', width: '20%'},
        // {label: '状态', value: 'status', width: '20%'},
        {label: '操作', value: 'action', width: '30%'},
      ],
      thStyles: {},
      loadingCount: 0
    }
  },
  computed: {
    filePathsList () {
      return this.filesList.map(v => v.path)
    }
  },
  filters: {
    formatFileSize (val) {
      return formatFileSize(val)
    }
  },
  mounted () {
  },
  methods: {
    checkScroll () {
      this.$nextTick(() => {
        if (!this.$refs.table) return
        let tableHeight = this.$refs.table.clientHeight
        let tableParentHeight = this.$refs.table.parentNode.clientHeight
        if (tableHeight > tableParentHeight) {
          this.thStyles = {overflow: 'hidden scroll'}
        } else {
          this.thStyles = {overflow: 'hidden'}
        }
      })
    },
    // 拖拽添加文件
    filesDrop (e) {
      const fileList = e.dataTransfer.files
      if (!fileList) return
      // 取文件后缀名，必须是uc文件
      let list = [...this.filesList]
      for (let i = 0; i < fileList.length; i++) {
        const file = fileList[i]
        if (!/.uc$/i.test(file.name)) {
          continue
        }
        if (!this.filePathsList.includes(file.path)) {
          list.push({
            name: file.name, path: file.path, status: 0
          })
        }
      }
      this.filesList = list
    },
    // 删除文件
    fileItemDelete (index) {
      this.filesList.splice(index, 1)
      this.checkScroll()
    },
    // 清空
    clearAll () {
      this.filesList = []
    },
    // 处理单个文件
    deSingleFile (index) {
      let file = this.filesList[index]
      let _arr = file.name.split('.')
      let _name = _arr.slice(0, _arr.length - 1).join('.')
      let toPath = path.join(path.dirname(file.path), `${_name}.mp3`)
      return new Promise((resolve, reject) => {
        if (!fs.existsSync(file.path)) {
          reject('文件不存在')
        }
        fs.readFile(file.path, (err, data) => {
          if (err || !data) reject('读取文件错误')
          data = data.map(v => (v ^ 0xA3))
          resolve(data)
        })
      }).then((data) => {
        return this.$sharedObject('jstoolsNode').writeFile(toPath, data)
      })
    },
    // 全部处理
    submitForm () {
      let taskList = []
      for (let i = 0; i < this.filesList.length; i++) {
        taskList.push(this.deSingleFile(i))
      }
      this.loadingCount++
      Promise.all(taskList).finally(() => {
        this.$toast('文件处理完成')
        this.loadingCount--
      })
    },
  }
}
</script>

<style scoped lang="less">
@import "~@/assets/css/_mixins.less";
@import "~@/assets/css/_color.less";
.row-flex {
  & + .row-flex {
    margin-top: .5em;
  }
  .row-flex-prefix {
    width: 4.5em;
    text-align: left;
  }
}
.form {
  height: calc(100vh - 137px);
  display: flex;
  flex-direction: column;
  .form-group {
    margin-top: .5em;
    fieldset {
      height: 100%;
    }
  }
  .form-main {
    height: 0;
    flex-grow: 1;
  }
	.fieldset-content {
    height: calc(100% - 2em);
    .table-header,
    .table-body {
      table {
        width: 100%;
        border: 1px solid @borderGrey;
        tr {height: 2em;}
        th, td {
          border: 1px solid @borderGrey;
          text-align: center;
          vertical-align: middle;
        }
        .nodata-tr {
          height: 100%;
          font-size: 16px;
          color: #999;
        }
      }
    }
    .table-body {
      height: calc(100% - 2em);
      overflow: auto;
      table {
        min-height: 100%;
      }
    }
  }
}
</style>
